<template>
    <div class="dnd-app">
      <div class="dnd-wrap" ref="dndContainer">
        <div
          data-type="rect"
          class="dnd-rect"
          @mousedown="startDrag"
        >
          Rect
        </div>
        <div
          data-type="circle"
          class="dnd-circle"
          @mousedown="startDrag"
        >
          Circle
        </div>
      </div>
  
      <div class="app-content" ref="container" />
    </div>
  </template>
  
  <script setup lang="ts">
  import { onMounted, ref } from 'vue'
  import { Graph } from '@antv/x6'
  import { Dnd } from '@antv/x6-plugin-dnd'
  import { Snapline } from '@antv/x6-plugin-snapline'
  import './index.less'
  
  const container = ref<HTMLDivElement | null>(null)
  const dndContainer = ref<HTMLDivElement | null>(null)
  let graph: Graph
  let dnd: Dnd
  
  onMounted(() => {
    graph = new Graph({
      container: container.value!,
      background: {
        color: '#F2F7FA',
      },
      mousewheel: {
        enabled: true,
        modifiers: ['ctrl', 'meta'],
      },
    })
  
    graph.use(
      new Snapline({
        enabled: true,
        sharp: true,
      }),
    )
  
    const source = graph.addNode({
      x: 130,
      y: 30,
      width: 100,
      height: 40,
      label: 'Hello',
      attrs: {
        body: {
          stroke: '#8f8f8f',
          strokeWidth: 1,
          fill: '#fff',
          rx: 6,
          ry: 6,
        },
      },
    })
  
    const target = graph.addNode({
      x: 180,
      y: 160,
      width: 100,
      height: 40,
      label: 'World',
      attrs: {
        body: {
          stroke: '#8f8f8f',
          strokeWidth: 1,
          fill: '#fff',
          rx: 6,
          ry: 6,
        },
      },
    })
  
    graph.addEdge({
      source,
      target,
      attrs: {
        line: {
          stroke: '#8f8f8f',
          strokeWidth: 1,
        },
      },
    })
    graph.centerContent()
  
    dnd = new Dnd({
      target: graph,
      scaled: false,
      dndContainer: dndContainer.value!,
    })
  })
  
  const startDrag = (e: MouseEvent) => {
    const target = e.currentTarget as HTMLDivElement
    const type = target.getAttribute('data-type')
    const node =
      type === 'rect'
        ? graph.createNode({
            width: 100,
            height: 40,
            label: 'Rect',
            attrs: {
              body: {
                stroke: '#8f8f8f',
                strokeWidth: 1,
                fill: '#fff',
                rx: 6,
                ry: 6,
              },
            },
          })
        : graph.createNode({
            width: 60,
            height: 60,
            shape: 'circle',
            label: 'Circle',
            attrs: {
              body: {
                stroke: '#8f8f8f',
                strokeWidth: 1,
                fill: '#fff',
              },
            },
          })
  
    dnd.start(node, e)
  }
  </script>
  
  <style lang="less" scoped>
  .dnd-app {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100vh;
  }
  
  .dnd-wrap {
    display: flex;
    gap: 10px;
    margin-bottom: 20px;
  }
  
  .dnd-rect, .dnd-circle {
    padding: 10px;
    background-color: #f0f0f0;
    border: 1px solid #ccc;
    cursor: move;
  }
  
  .app-content {
    width: 1200px;
    height: 880px;
    border: 1px solid #ccc;
  }
  </style>